C#调用C++动态库,参数包含string/wstring,如何处理?

在C++中写了一个简单的函数如下:
头文件:

1
void __declspec(dllexport) GetUnicodeString(wstring& str);

实现文件:

1
2
3
4
void GetUnicodeString(wstring& str)
{
str = L"This is a String in C++ Dll";
}

在C#中,通过Dllimport的方式引入:

1
2
3
4
5
6
7
8
9
10
11
[DllImport(@"Test.dll",               
EntryPoint = "XXXXX",
CallingConvention = CallingConvention.Cdecl,
CharSet = CharSet.Unicode)]
public static extern void GetUnicodeString(ref string str);
static void Main(string[] args)
{
string str = "This is a String in C# .....";
GetUnicodeString(ref str);
Console.Read();
}

遗憾的是在调用GetUnicodeString(ref str);的时候崩溃了,按理说C#和C++是两个语言,这样用string传入风险值很大,但是竟然有个同事一直这样用了很久。。。难以理解。
要想C#调用C++的函数,只能用原生态的参数(char,wchar_t),故把C++的函数改为:

1
2
3
4
void GetUnicodeString(wchar_t* wstr, int len)
{
wcscpy_s(wstr, len, L"This is a String in C++ Dll");
}

然后C#在使用时,以Byte申请空间传入,最后转为Unicode字符串

1
2
3
4
5
6
7
8
9
public static extern void GetUnicodeString(ref Byte str, int len);
static void Main(string[] args)
{
Byte[] buffer = new Byte[257 * 2];
GetUnicodeString(ref buffer[0], 256);
string str = UnicodeEncoding.Unicode.GetString(buffer);
Console.WriteLine(str);
Console.Read();
}

终于,得到了返回的字符串值This is a String in C++ Dll